package com.rst.service;

import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;

import com.rst.dao.AuthenticationDAO;
import com.rst.model.UserDetailsDTO;

public class AuthenticationService implements UserDetailsManager,UserDetailsService {
	
	private Logger logger = Logger.getLogger(AuthenticationService.class);
	
	private AuthenticationDAO authenticationDAO;
	public AuthenticationDAO getAuthenticationDAO() {
		return authenticationDAO;
	}

	public void setAuthenticationDAO(AuthenticationDAO authenticationDAO) {
		this.authenticationDAO = authenticationDAO;
	}

	
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		
		logger.debug("in method loadUserByUsername for userId: " + username);
		
		UserDetailsDTO userDetails = null;
		try {
			userDetails = authenticationDAO.getDetailsForUserId(username);
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e.getMessage());
		}
		
		Properties propertyFile = new Properties();
		String enableCredentialAutoExpiry = null;
		try {
			propertyFile.load(AuthenticationService.class.getResourceAsStream("/switches.properties"));
			enableCredentialAutoExpiry = propertyFile.getProperty("enableCredentialAutoExpiry");
		} catch (IOException e) {
			logger.debug(e.getMessage(),e);
		}
		if(enableCredentialAutoExpiry.equalsIgnoreCase("1")) {
			logger.debug("Credential expiry check enabled");
			//credentialsExpired(userDetails);	
		}
		return userDetails; 
	}
	
	public void createUser(UserDetails user) {}

	public void deleteUser(String username) {}

	public void updateUser(UserDetails user) {}

	public boolean userExists(String username) {
		return false;
	}
	
	public UserDetailsDTO credentialsExpired(UserDetailsDTO userDetailsDTO){
		
		if(null == userDetailsDTO)
			return userDetailsDTO;
		
/*		logger.debug("inside method credentialsExpired for user: " 
				+ userDetailsDTO.getFirstName()+userDetailsDTO.getLastName()+"("+userDetailsDTO.getUserId()+")");
*/		

		Integer numberOfDaysForExpiry=null;
		try {
			Properties propertyFile = new Properties();
			propertyFile.load(AuthenticationService.class.getResourceAsStream("/switches.properties"));
			String numberOfDaysForCredentialExpiry = propertyFile.getProperty("numberOfDaysForCredentialExpiry");
			numberOfDaysForExpiry = Integer.valueOf(numberOfDaysForCredentialExpiry);
		}
		catch(Exception e) {
			logger.debug(e.getMessage(),e);
		}
		
		if(null == numberOfDaysForExpiry)
			numberOfDaysForExpiry = 0;
		
		if(userDetailsDTO.getCreatedDate() == null){
			Date createddate = userDetailsDTO.getCreatedDate();
			
			logger.debug("IF UPDATED DATE IS NULL");
			
			Date newdate = new Date();
			
			long milliseconds1 = createddate.getTime();
			long milliseconds2 = newdate.getTime();
			
			logger.debug("MILLISECONDS 1 " + milliseconds1);
			logger.debug("MILLISECONDS 1 " + milliseconds2);
			
			long diff = milliseconds2 - milliseconds1;
			long diffdays = diff / (24 * 60 * 60 * 1000);
			
			logger.debug("DIFFERENCE OF DAYS: " + diffdays);
			
/*			if(diffdays > numberOfDaysForExpiry){
				userDetailsDTO.setCredentialsExpired(true);
			}
*/		
		}
		else if(userDetailsDTO.getUpdatedDate()!= null){
			logger.debug("IF UPDATED DATE IS NOT NULL");
			
			Date updateddate = userDetailsDTO.getUpdatedDate();
			Date newdate = new Date();
			
			logger.debug("UPDATED DATE" + updateddate);
			
			long milliseconds1 = updateddate.getTime();
			long milliseconds2 = newdate.getTime();
			
			logger.debug("MILLISECONDS 1 " + milliseconds1);
			logger.debug("MILLISECONDS 1 " + milliseconds2);
			
			long diff = milliseconds2 - milliseconds1;
			long diffdays = diff / (24 * 60 * 60 * 1000);
			
			logger.debug("DIFFERENCE OF DAYS: " + diffdays);
			
/*			if(diffdays > numberOfDaysForExpiry){
				userDetailsDTO.setCredentialsExpired(true);
			}
*/		}
		return userDetailsDTO;
	}
	
	public void accountLocked(UserDetailsDTO detailsDTO){
/*		if(null != detailsDTO.getCount())
			detailsDTO.setCount(detailsDTO.getCount().intValue()+1);
*/		
		//logger.debug("VALUE OF COUNT: " + detailsDTO.getCount());
		
		//String numberOfAttemptsForAccountLocking = null;
		try {
			Properties propertyFile = new Properties();
			propertyFile.load(AuthenticationService.class.getResourceAsStream("/switches.properties"));
			//numberOfAttemptsForAccountLocking = propertyFile.getProperty("numberOfAttemptsForAccountLocking");
		}
		catch(Throwable e) {
			logger.debug(e.getMessage(),e);
		}
		
/*		if(detailsDTO.getCount().intValue() >= Integer.valueOf(numberOfAttemptsForAccountLocking).intValue()){
			detailsDTO.setAccountNonLocked(false);
		}*/
	
		try {
			authenticationDAO.updateUserDetails(detailsDTO);
		} 
		catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
	}

	public void changePassword(String arg0, String arg1) {}
	
	public void updateUserDetails(UserDetailsDTO detailsDTO) {
		try {
			authenticationDAO.updateUserDetails(detailsDTO);
		} catch (Exception e) {
			logger.debug(e.getMessage(),e);
		}
	}
}